package com.group3.service.impl;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.group3.config.ServerConfig;
import com.group3.dao.*;
import com.group3.domain.*;
import com.group3.exception.BusinessException;
import com.group3.exception.ExceptionEnum;
import com.group3.pojo.receive.PunchReceive;
import com.group3.service.APunchService;
import com.group3.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.List;

@Service
public class APunchServiceImpl implements APunchService {

    @Autowired
    private ServerConfig serverConfig;
    @Resource
    private PunchAttendanceMapper punchAttendanceMapper;
    @Resource
    private PunchRecordMapper punchRecordMapper;
    @Resource
    private AttendanceLeaveMapper attendanceLeaveMapper;
    @Resource
    private AttendanceLeaveStartMapper attendanceLeaveStartMapper;
    @Resource
    private AttendanceLeaveEndMapper attendanceLeaveEndMapper;
    @Resource
    private AttendanceMapper attendanceMapper;

    @Override
    @Transactional
    public Result addClock(MultipartFile file, String token) {
        ExcelData excelToDB = new ExcelData();
        List<PunchRecord> punchRecords;
        try {
            punchRecords = excelToDB.punchRecord(file);
        } catch (Exception e) {
            throw new BusinessException(ExceptionEnum.EXCEL_ERR);
        }
        if (punchRecords.size() > 0){
            for (PunchRecord punchRecord : punchRecords){
                punchRecordMapper.insertSelective(punchRecord);
            }

            PunchRecord firstPunch = punchRecords.get(0);//第一条数据即最早打卡的数据
            PunchRecord lastPunch = punchRecords.get(punchRecords.size()-1);//最后打卡的数据

            PunchAttendanceExample example = new PunchAttendanceExample();
            example.createCriteria()//获取打卡记录范围内的考勤
                    .andEndTimeBetween(firstPunch.getPunchTime(),lastPunch.getPunchTime());
            List<PunchAttendance> punchAttendances
                    = punchAttendanceMapper.selectByExample(example);

            for (PunchAttendance punchAttendance : punchAttendances){
                AttendanceJudge judge = new AttendanceJudge(punchRecords);
                PunchAttendance attendance
                        = judge.punchJudge(punchAttendance);//判断该考勤记录的状态

                //更新考勤状态
                PunchAttendanceExample punchAttendanceExample = new PunchAttendanceExample();
                punchAttendanceExample
                        .createCriteria()
                        .andAttendanceIdEqualTo(punchAttendance.getAttendanceId());
                punchAttendanceMapper.updateByExampleSelective(attendance,punchAttendanceExample);
            }

            //找到该时间段内已经请假的考勤记录
            AttendanceLeaveExample attendanceLeaveExample = new AttendanceLeaveExample();
            attendanceLeaveExample
                    .createCriteria()
                    .andEndTimeBetween(firstPunch.getPunchTime(),lastPunch.getPunchTime());
            List<AttendanceLeave> attendanceLeaves =
                    attendanceLeaveMapper.selectByExample(attendanceLeaveExample);
            for (AttendanceLeave attendanceLeave : attendanceLeaves){
                Attendance attendance = new Attendance();
                attendance.setAttendanceType(6);
                attendance.setAttendanceId(attendanceLeave.getAttendanceId());//获取主键
                attendance.setLeaveId(attendanceLeave.getLeaveId());//获取请假id
                attendanceMapper.updateByPrimaryKeySelective(attendance);//更新该记录
            }
            //找到该时间段包含上课开始时间不包含上课结束时间的考勤
            AttendanceLeaveStartExample startExample = new AttendanceLeaveStartExample();
            startExample
                    .createCriteria()
                    .andEndTimeBetween(firstPunch.getPunchTime(),lastPunch.getPunchTime());
            List<AttendanceLeaveStart> leaveStarts =
                    attendanceLeaveStartMapper.selectByExample(startExample);
            for (AttendanceLeaveStart leaveStart : leaveStarts){
                Attendance attendance = new Attendance();
                attendance.setAttendanceType(3);
                attendance.setAttendanceId(leaveStart.getAttendanceId());//获取主键
                attendance.setLeaveId(leaveStart.getLeaveId());//获取请假id
                attendanceMapper.updateByPrimaryKeySelective(attendance);//更新该记录
            }
            //找到该事件段包含上课结束时间不包含上课开始时间的考勤
            AttendanceLeaveEndExample endExample = new AttendanceLeaveEndExample();
            startExample
                    .createCriteria()
                    .andEndTimeBetween(firstPunch.getPunchTime(),lastPunch.getPunchTime());
            List<AttendanceLeaveEnd> leaveEnds =
                    attendanceLeaveEndMapper.selectByExample(endExample);
            for (AttendanceLeaveEnd leaveEnd : leaveEnds){
                Attendance attendance = new Attendance();
                attendance.setAttendanceType(2);
                attendance.setAttendanceId(leaveEnd.getAttendanceId());//获取主键
                attendance.setLeaveId(leaveEnd.getLeaveId());//获取请假id
                attendanceMapper.updateByPrimaryKeySelective(attendance);//更新该记录
            }

        }
        return ResultUtil.success();
    }

    @Override
    @Transactional
    public Result addTemplate(MultipartFile file, String token) {

        UploadUtil uploadUtil = new UploadUtil();


        DecodedJWT jwt = JWTUtils.getToken(token);//获取token
        String studentId = jwt.getClaim("id").asString();//获取登录学生的id

        //保存上传图片至指定路径
        uploadUtil.doUpload(file, "images/stores", studentId);

        //拼接图片地址
        String url = serverConfig.getUrl() + uploadUtil.getUploadFile();

        return ResultUtil.success();
    }

    @Override
    @Transactional
    public Result GetClock() {

        return ResultUtil.success();
    }

    @Override
    @Transactional
    public Result selectClock(PunchReceive punchReceive) {

        PunchRecordExample punchRecordExample = new PunchRecordExample();
        PunchRecordExample.Criteria criteria = punchRecordExample.createCriteria();

        if (NotNull.judge(punchReceive.getStartTime())){
            criteria.andPunchTimeGreaterThanOrEqualTo(punchReceive.getStartTime());
        }
        if (NotNull.judge(punchReceive.getEndTime())){
            criteria.andPunchTimeLessThanOrEqualTo(punchReceive.getEndTime());
        }
        if (NotNull.judge(punchReceive.getStudenId())){
            criteria.andStudentIdEqualTo(punchReceive.getStudenId());
        }
        if (NotNull.judge(punchReceive.getStudentName())){
            criteria.andStudentNameLike("%"+(punchReceive.getStudentName())+"%");
        }

//        1.先开启分页
        PageHelper.startPage(punchReceive.getPageNumber(), punchReceive.getPageSize());

//        2.执行SQL语句
        List<PunchRecord> punchRecords = punchRecordMapper.selectByExample(punchRecordExample);
//        3.获取分页信息
        PageInfo<PunchRecord> PunchRecordPageInfo = new PageInfo<>(punchRecords);

        return ResultUtil.success("查询成功", punchRecords, PunchRecordPageInfo.getTotal());
    }
}
